﻿#pragma once

#include <hacks/base/ev_loop.h>

namespace hacks {
    class ev_timer;

    SHARED_TYPE(ev_timer);

    typedef std::function<void(ev_timer &)> ev_timer_functor_t;

    class ev_timer : public std::enable_shared_from_this<ev_timer> {
    DISABLE_COPY_MOVE(ev_timer)

    public:

        ev_timer(const shared_ev_loop &loop,
                 ev_timer_functor_t &&tick_f,
                 std::size_t timeout,
                 std::size_t repeat);

        ev_timer(const shared_ev_loop &loop,
                 ev_timer_functor_t &&tick_f,
                 ev_timer_functor_t &&close_f,
                 std::size_t timeout,
                 std::size_t repeat);

        ~ev_timer();

        std::size_t get_repeat() const;

        std::size_t get_timeout() const;

        //commit to loop
        void commit();

        //重新开始计时
        void restart_timer() const;

        //停止计时
        void stop_timer();

        shared_ev_loop &get_event_loop();

        void set_userdata(void *udata);

        void *get_userdata() const;

    private:
        void init();

        static void uv_timer_event_callback(uv_timer_t *timer);

        void ev_timer_tick_callback();

        static void uv_timer_close_callback(uv_handle_t *hd);

        void ev_timer_close_callback();

    private:
        shared_ev_loop event_loop_;
        uv_timer_t *timer_;
        ev_timer_functor_t timer_tick_functor_;
        ev_timer_functor_t timer_close_functor_;
        std::size_t timeout_;
        std::size_t repeat_;
        std::once_flag commit_once_flag_;
        std::atomic<ev_evt_state> timer_status_;
        void *user_data_;
    };
}
